﻿using AutoMapper;
using wwl.Contract.Dtos.Common;
using wwl.Contract.Dtos.Requests.Rbac;
using wwl.Contract.Dtos.Responses.Rbac;
using wwl.Contract.Interfaces.Rbac;
using wwl.Contract.Interfaces.Security;
using wwl.Domain.Entities.Rbac;

namespace wwl.Application.Services.Rbac
{
  /// <summary>
  /// 用户领域服务实现
  /// 封装用户相关的完整业务流程，协调领域实体与仓储完成核心业务操作
  /// </summary>
  public class UserService : IUserService
  {
    private readonly IUserRepository _repository;
    private readonly IMapper _mapper;
    private readonly PasswordService _passwordService;

    /// <summary>
    /// 初始化用户服务
    /// </summary>
    public UserService(IUserRepository repository, IMapper mapper, PasswordService passwordService)
    {
      _repository = repository;
      _mapper = mapper;
      _passwordService = passwordService;
    }

    /// <summary>
    /// 根据ID查询用户
    /// </summary>
    public async Task<UserResponse?> GetByIdAsync(string id)
    {
      var entity = await _repository.GetByIdAsync(id);
      return entity == null ? null : _mapper.Map<UserResponse>(entity);
    }

    /// <summary>
    /// 创建用户（包含密码哈希处理）
    /// </summary>
    public async Task<UserResponse> CreateAsync(CreateUserRequest request, string createdBy)
    {
      // 校验用户名唯一性
      if (await _repository.ExistsByUsernameAsync(request.Username))
      {
        throw new Exception($"用户名 '{request.Username}' 已存在");
      }

      // 校验邮箱唯一性
      if (!string.IsNullOrEmpty(request.Email) && await _repository.ExistsByEmailAsync(request.Email))
      {
        throw new Exception($"邮箱 '{request.Email}' 已被使用");
      }

      // 构建领域实体
      var entity = new User
      {
        Username = request.Username,
        FullName = request.FullName,
        Email = request.Email!,
        Phone = request.Phone,
        CreatedBy = createdBy,
        Remarks = request.Remarks ?? string.Empty
      };

      // 设置密码（自动进行哈希处理）
      _passwordService.SetUserPassword(entity, request.Password, PasswordStrength.Medium);

      // 调用仓储新增实体
      var result = await _repository.AddAsync(entity);
      return _mapper.Map<UserResponse>(result);
    }

    /// <summary>
    /// 更新用户信息
    /// </summary>
    public async Task<UserResponse> UpdateAsync(string id, UpdateUserRequest request)
    {
      var entity = await _repository.GetByIdAsync(id);
      if (entity == null)
      {
        throw new Exception($"用户 '{id}' 未找到");
      }

      // 更新字段
      entity.FullName = request.FullName;
      entity.Email = request.Email!;
      entity.Phone = request.Phone;

      if (!string.IsNullOrEmpty(request.Status) &&
          Enum.TryParse<UserStatus>(request.Status, out var status))
      {
        entity.Status = status;
      }

      entity.Remarks = request.Remarks ?? string.Empty;

      var result = await _repository.UpdateAsync(entity);
      return _mapper.Map<UserResponse>(result);
    }

    /// <summary>
    /// 删除用户
    /// </summary>
    public async Task<bool> DeleteAsync(string id)
    {
      return await _repository.SoftDeleteAsync(id);
    }

    /// <summary>
    /// 分页查询用户
    /// </summary>
    public async Task<PagedResult<UserResponse>> GetPagedAsync(UserPagedRequest request)
    {
      var result = await _repository.GetPagedAsync(request);
      return _mapper.Map<PagedResult<UserResponse>>(result);
    }

    /// <summary>
    /// 用户登录认证
    /// </summary>
    public async Task<UserResponse?> AuthenticateAsync(string username, string password)
    {
      var user = await _repository.GetByUsernameAsync(username);
      if (user == null || user.IsDeleted)
        return null;

      // 验证密码
      if (!_passwordService.VerifyUserPassword(user, password))
        return null;

      // 检查用户状态
      if (user.Status != UserStatus.ENABLED)
        return null;

      return _mapper.Map<UserResponse>(user);
    }

    /// <summary>
    /// 重置用户密码
    /// </summary>
    public async Task<bool> ResetPasswordAsync(string userId, string newPassword)
    {
      var user = await _repository.GetByIdAsync(userId);
      if (user == null || user.IsDeleted)
        return false;

      _passwordService.SetUserPassword(user, newPassword, PasswordStrength.Medium);
      await _repository.UpdateAsync(user);
      return true;
    }

    /// <summary>
    /// 验证当前密码
    /// </summary>
    public async Task<bool> VerifyCurrentPasswordAsync(string userId, string currentPassword)
    {
      var user = await _repository.GetByIdAsync(userId);
      if (user == null || user.IsDeleted)
        return false;

      return _passwordService.VerifyUserPassword(user, currentPassword);
    }
  }
}